﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twi.DataAccess.Common;
using Twi.COMMON.Core;
using System.Data;
using Twi.DataAccess.OutInterface;
using System.Data.Common;
using System.Xml.Linq;

namespace Twi.COMMON.Module
{
    public abstract class TwiModuleHelper : IPageCommon
    {
        /// <summary>
        /// 当前项目的英文缩写：如BIM、TSF、RDM...
        /// </summary>
        public virtual string ProjectAbbreviation
        {
            get;
            set;
        }
        /// <summary>
        /// WebConfig配置的数据库连接字符串
        /// <example>
        ///     如配置WebConfig里面配置：
        ///     <connectionStrings>
        ///         <add name="TABConnectionString" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.8)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)));User Id=tabms;Password=tabms;"
        ///              providerName="System.Data.OracleClient"/>
        ///     </connectionStrings>
        ///     那么ConfigConnectionString的值为：TABConnectionString
        /// </example>
        /// </summary>
        public virtual string ConfigConnectionString
        {
            get;
            set;
        }
        private string _defaultConnectionString = "DefaultConnectionString";
        private string _defaultTableMappingName = "TTableMapping";

        /// <summary>
        /// 表映射存储的表名
        /// </summary>
        public virtual string MappingTableName
        {
            get;
            set;
        }

        /// <summary>
        /// SQL-MAP 配置文件的完整路径
        /// </summary>
        public virtual string SQLMapFullPath
        {
            get;
            set;
        }

        /// <summary>
        /// TableMapping 配置文件的完整路径
        /// </summary>
        public virtual string TableMappingFullPath
        {
            get;
            set;
        }

        /// <summary>
        /// 最大记录编号存储信息
        /// </summary>
        public virtual DBMaxCode MaxCode
        {
            get;
            set;
        }
        /// <summary>
        /// 配置文件的虚拟路径。如："/Areas/BIM/Views"
        /// 如果为 null，则打开根 Web.config 文件.
        /// </summary>
        private string _webConfigPath;
        public virtual string WebConfigPath
        {
            get {
                if (string.IsNullOrEmpty(_webConfigPath)) {
                    _webConfigPath = "~/Config/TwiDBConnection.config";
                }
                return _webConfigPath;
            }
            set { _webConfigPath = value; }
        }

        private string _jsModelConfigPath;
        /// <summary>
        /// JS model 配置文件的虚拟路径。如："~/Areas/TSF/JSModel"
        /// </summary>
        public virtual string JSModelConfigPath
        {
            get
            {
                if (string.IsNullOrEmpty(_jsModelConfigPath))
                {
                    _jsModelConfigPath = string.Format("~/Areas/{0}/JSModel", ProjectAbbreviation);
                }
                return _jsModelConfigPath;
            }
            set { _jsModelConfigPath = value; }
        }

        public string GetJSModelJsonString(string jsModelFileName)
        {
            return "";
        }

        private DbUtility _db
        {
            get;
            set;
        }
        private DbUtility GetDB()
        {
            if (_db == null)
            {
                //如果没有配置，则取Web.Config中默认的连接
                string configConnStr = string.IsNullOrEmpty(ConfigConnectionString) ? _defaultConnectionString : ConfigConnectionString;
                string connStr = null;
                string providerName = null;

                //【优先】如果有Twi数据库连接统一配置文件：~/Config/TwiDBConnection.xml,则优先读取
                var twiDBConn = TwiDBConnectionHelper.GetInstance();
                connStr = twiDBConn.GetConnectionStringByName(configConnStr);
                connStr = connStr == null ? twiDBConn.GetConnectionStringByName(_defaultConnectionString) : connStr;
                if (connStr != null)
                {
                    providerName = twiDBConn.GetFirstOrDefaultByAttribute("name", configConnStr, "providerName");
                    providerName = providerName == null ? twiDBConn.GetFirstOrDefaultByAttribute("name", _defaultConnectionString, "providerName") : providerName;
                }
                else
                {
                    connStr = TwiConfigHelper.GetConnectionString(configConnStr, WebConfigPath);
                    providerName = TwiConfigHelper.GetProviderName(configConnStr, WebConfigPath);
                    connStr = string.IsNullOrEmpty(connStr) ? TwiConfigHelper.GetConnectionString(_defaultConnectionString) : connStr;
                    providerName = string.IsNullOrEmpty(providerName) ? TwiConfigHelper.GetProviderName(_defaultConnectionString) : providerName;
                }
                _db = new DbUtility(connStr, providerName);
            }
            return _db;
        }
        /// <summary>
        /// 对外公开DbUtility
        /// </summary>
        public DbUtility DB
        {
            get
            {
                return GetDB();
            }
        }


        private DACommon _DACommonHelper
        {
            get;
            set;
        }
        private DACommon GetDACommonHelper()
        {
            if (_DACommonHelper == null)
            {
                MappingTableName = string.IsNullOrEmpty(MappingTableName) ? _defaultTableMappingName : MappingTableName;
                _DACommonHelper = new DACommon(DB, MappingTableName);
                _DACommonHelper.SQLMapFullPath = SQLMapFullPath;
                _DACommonHelper.TableMappingFullPath = TableMappingFullPath;
                if (MaxCode == null) MaxCode = new DBMaxCode();
                MaxCode.DB = DB;
                _DACommonHelper.MaxCode = MaxCode;
            }
            return _DACommonHelper;
        }
        /// <summary>
        /// 对外公开 DACommon
        /// </summary>
        public DACommon DACommonHelper
        {
            get
            {
                return GetDACommonHelper();
            }
        }


        /// <summary>
        /// 参数前缀@ ：?
        /// </summary>
        public string ParameterPrefix
        {
            get
            {
                if (DB._DbProviderType == DbProviderType.Oracle)
                {
                    return ":";
                }
                else if (DB._DbProviderType == DbProviderType.OracleDataAccess)
                {
                    return ":";
                }
                else
                {
                    return "@";
                }
            }
        }

        private DBHelper _dbHelper
        {
            get;
            set;
        }
        private DBHelper GetDBHelper()
        {
            if (_dbHelper == null)
            {
                _dbHelper = new DBHelper(DB, ParameterPrefix, MappingTableName);
                _dbHelper.TableMappingFullPath = TableMappingFullPath;
            }
            return _dbHelper;
        }
        /// <summary>
        /// 对外公开 DBHelper
        /// </summary>
        public DBHelper dbHelper
        {
            get
            {
                return GetDBHelper();
            }
        }

        public DataTable ColNameToUpper(DataTable dt)
        {
            return DACommonHelper.ColNameToUpper(dt);
        }

        public bool ExistField(string tableName, string fieldName, string fieldValue)
        {
            return DACommonHelper.ExistField(tableName, fieldName, fieldValue);
        }

        public bool ExistField(string tableName, string fieldName, string fieldValue, string id, string idField = "FID")
        {
            return DACommonHelper.ExistField(tableName, fieldName, fieldValue, id, idField);
        }


        public bool ExistEditSort(string tableName, int? sort, string id, string filterField, string filterFieldValue, string sortField = "FSort", string idField = "FID")
        {
            return DACommonHelper.ExistEditSort(tableName, sort, id, filterField, filterFieldValue, sortField, idField);
        }

        public bool ExistEditSort(string tableName, int? sort, string id, string sortField = "FSort", string idField = "FID")
        {
            return DACommonHelper.ExistEditSort(tableName, sort, id, sortField, idField);
        }

        public bool ExistSort(string tableName, int? sort, string filterField, string filterFieldValue, string sortField = "FSort")
        {
            return DACommonHelper.ExistSort(tableName, sort, filterField, filterFieldValue, sortField);
        }

        public bool ExistSort(string tableName, int? sort, string sortField = "FSort")
        {
            return DACommonHelper.ExistSort(tableName, sort, sortField);
        }

        public int GetMaxSort(string tableName, string filterField, string filterFieldValue, string sortField = "FSort")
        {
            return DACommonHelper.GetMaxSort(tableName, filterField, filterFieldValue, sortField);
        }

        public int GetMaxSort(string tableName, string sortField = "FSort")
        {
            return DACommonHelper.GetMaxSort(tableName, sortField);
        }

        public int GetCountByCondition(string data)
        {
            return DACommonHelper.GetCountByCondition(data);
        }


        public void Delete(string tableName, string[] ids, string idField = "FID")
        {
            DACommonHelper.Delete(tableName, ids, idField);
        }

        public void Delete(string tableName, string id, string idField = "FID")
        {
            DACommonHelper.Delete(tableName, id, idField);
        }

        public void DeleteBySetFlag(string data)
        {
            DACommonHelper.DeleteBySetFlag(data);
        }

        public void DeleteBySetFlag(string tableName, string[] ids, string idField = "FID", string deleteField = "FIsDeleted", string value = "1")
        {
            DACommonHelper.DeleteBySetFlag(tableName, ids, idField, deleteField, value);
        }

        public DataTable GetAll(string tableName, string selectFields = "*", string orderFields = null)
        {
            return DACommonHelper.GetAll(tableName, selectFields, orderFields);
        }

        public DataTable GetByID(string tableName, string id, string idField = "FID", string selectFields = "*", bool needMappingTable = true)
        {
            return DACommonHelper.GetByID(tableName, id, idField, selectFields, needMappingTable);
        }

        public object GetScalarByID(string tableName, string id, string idField = "FID", string selectFields = "*", bool needMappingTable = true)
        {
            return DACommonHelper.GetScalarByID(tableName, id, idField, selectFields, needMappingTable);
        }

        public DataTable GetBySimpleCondition(string data)
        {
            return DACommonHelper.GetBySimpleCondition(data);
        }

        public DataTable GetBySimpleCondition(string tableName, Dictionary<string, object> dictCondition, SimpleCondition simpleCondition, string selectFields = "*", string orderFields = null)
        {
            return DACommonHelper.GetBySimpleCondition(tableName, dictCondition, simpleCondition, selectFields, orderFields);
        }

        public DataTable GetPagingDataByCondition(string data, PagingCondition paging = null)
        {
            return DACommonHelper.GetPagingDataByCondition(data, paging);
        }

        public DataTable GetPagingDataByCondition(string tableName, Dictionary<string, object> dictCondition, SimpleCondition simpleCondition, string selectFields = "*", string orderFields = null, PagingCondition paging = null)
        {
            return DACommonHelper.GetPagingDataByCondition(tableName, dictCondition, simpleCondition, selectFields, orderFields, paging);
        }

        public DataTable GetPagingData(string strSql, IList<DbParameter> dbParams, PagingCondition paging)
        {
            return DACommonHelper.GetPagingData(strSql, dbParams, paging);
        }

        public DataTable GetByComplexCondition(string data, PagingCondition paging = null)
        {
            return dbHelper.GetByComplexCondition(data, paging);
        }

        public DataTable GetPagingDataByCondition(int start, int limit, string twiData)
        {
            return DACommonHelper.GetPagingDataByCondition(start, limit, twiData);
        }

        public string NewOrEdit(string data)
        {
            return DACommonHelper.NewOrEdit(data);
        }

        public string SimpleNew(string data)
        {
            return DACommonHelper.SimpleNew(data);
        }

        public string SimpleNew(string tableName, Dictionary<string, object> dictFields, Dictionary<string, string> dictFnFields = null, Dictionary<string, string> dictMaxCodeFields = null)
        {
            return DACommonHelper.SimpleNew(tableName, dictFields, dictFnFields, dictMaxCodeFields);
        }


        public void SimpleEdit(string tableName, Dictionary<string, object> dictUpdateFields, Dictionary<string, object> dictConditionFields)
        {
            DACommonHelper.SimpleEdit(tableName, dictUpdateFields, dictConditionFields);
        }

        public void SimpleEdit(string data)
        {
            DACommonHelper.SimpleEdit(data);
        }

        public DataTable GetBySQLMap(string data)
        {
            return DACommonHelper.GetBySQLMap(data);
        }

        public DataTable GetBySQLMap(SQLMapModel model)
        {
            return DACommonHelper.GetBySQLMap(model);
        }

        /// <summary>
        /// 根据SQL-MAP查询分页数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="paging"></param>
        /// <returns></returns>
        public DataTable GetPagingDataBySQLMap(string data, PagingCondition paging = null)
        {
            return DACommonHelper.GetPagingDataBySQLMap(data, paging);
        }

        public void ExecuteBySQLMap(string data)
        {
            DACommonHelper.ExecuteBySQLMap(data);
        }

        public void ExecuteBySQLMap(SQLMapModel model)
        {
            DACommonHelper.ExecuteBySQLMap(model);
        }

        /// <summary>
        /// 根据SQL-MAP查询数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public XElement GetXmlBySQLMap(SQLMapModel model)
        {
            return DACommonHelper.GetXmlBySQLMap(model);
        }

        public XElement GetXmlBySQLMap(string data)
        {
            return DACommonHelper.GetXmlBySQLMap(data);
        }
        public XElement SimpleInsertXml(XElement data)
        {
            return DACommonHelper.SimpleInsertXml(data);
        }

        public XElement DeleteXml(XElement data)
        {
            return DACommonHelper.DeleteXml(data);
        }
        public XElement GetSingleXml(XElement data)
        {
            return DACommonHelper.GetSingleXml(data);
        }
        public XElement SimpleUpdateXml(XElement data)
        {
            return DACommonHelper.SimpleUpdateXml(data);
        }

        public XElement Process(Action<XElement, TwiCommand> processDelegate)
        {
            TwiCommand cmd = DB.CreateCommand();
            XElement xe = new XElement("Root");
            try
            {
                processDelegate(xe, cmd);

                if (cmd.Transaction != null && cmd.IsAutoSubmitTran)
                {
                    cmd.Transaction.Commit();
                }
            }
            catch (Exception ex)
            {
                if (cmd.Transaction != null)
                {
                    cmd.Transaction.Rollback();
                }
                throw ex;
            }
            finally
            {
                if (cmd != null)
                {
                    if (cmd.DbConnection != null && cmd.DbConnection.State == System.Data.ConnectionState.Open)
                    {
                        cmd.DbConnection.Close();
                        cmd.DbConnection.Dispose();
                    }
                    cmd.Dispose();
                }
            }
            return xe;
        }
        public XElement Process(Action<XElement, DbTransaction> processDelegate, DbConnection conn)
        {
            DbTransaction txn = conn.BeginTransaction();
            XElement xe = new XElement("Root");
            try
            {
                processDelegate(xe, txn);
            }
            catch (Exception ex)
            {
                txn.Rollback();
                throw ex;
            }
            finally
            {
                if (conn.State == System.Data.ConnectionState.Open)
                {
                    //有可能该事物已经回滚不能提交
                    if (conn is System.Data.SqlClient.SqlConnection)
                    {
                        DbCommand cmd = conn.CreateCommand();
                        cmd.CommandText = "select @@trancount";
                        cmd.Transaction = txn;

                        if ((int)cmd.ExecuteScalar() > 0)
                        {
                            txn.Commit();
                        }
                    }
                    else
                    {
                        txn.Commit();
                    }
                    txn.Dispose();
                }
            }
            return xe;
        }


        public void WriteSimpleLog(Dictionary<string, object> dict) {
             DACommonHelper.WriteSimpleLog(dict);
        }

                /// <summary>
        /// 获取数据库时间
        /// </summary>
        /// <returns></returns>
        public string GetDBNowDateTime() {
            return DACommonHelper.GetDBNowDateTime();
        }
    }
}
